----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    16:29:55 07/26/2009 
-- Design Name: 
-- Module Name:    mont_mult - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--use IEEE.NUMERIC_STD.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity mont_mult is
    Port ( a : in  STD_LOGIC_VECTOR (1023 downto 0);
           b : in  STD_LOGIC_VECTOR (1023 downto 0);
           n : in  STD_LOGIC_VECTOR (1023 downto 0);
			  clk : in STD_LOGIC;
			  i_out : out integer := 0;
           s : out  STD_LOGIC_VECTOR (2047 downto 0));
end mont_mult;

architecture Behavioral of mont_mult is
	signal q0 : std_logic_vector (0 downto 0);
	signal q1 : std_logic_vector (0 downto 0);
	signal temp0 : std_logic_vector (0 downto 0);
	constant integer_bitlength : integer := 1024;

begin
	process (clk) is
		variable i : integer := 0;
		variable temp : std_logic_vector (2047 downto 0) := (others => '0');
		variable s0 : std_logic_vector (0 downto 0);
		variable s1 : std_logic;
		variable r0 : std_logic_vector (1023 downto 0) := (others => '0');
		variable r1 : std_logic_vector (1024 downto 0) := (others => '0');
		variable r2 : std_logic_vector (2047 downto 0) := (others => '0');
		variable r3 : std_logic_vector (2047 downto 0) := (others => '0');
		variable r4 : bit_vector (11 downto 0);
	begin
		if (i < integer_bitlength) then
			if (clk'event and clk = '1') then
				if (a(i) = '1') then
					q0(0) <= b(0);
				else
					q0(0) <= '0';
				end if;
				temp0(0) <= temp(0);
				q1 <= unsigned(q0) + unsigned(temp0);
				if (q1(0) = '1') then
					r0 := (others => '0');
				else
					r0 := n;
				end if;
				if (a(i) = '1') then
					r1 := r0 + b;
				else
					r1 := '0' & r0;
				end if;
				r2 := r1 + temp;
				temp := '0' & r2(2047 downto 1);
				i := i + 1;
				i_out <= i;
			end if;
		end if;
		if (unsigned(temp) >= unsigned(n)) then
			s <= unsigned(temp) - unsigned(n);
		else
			s <= temp;
		end if;
	end process;

end Behavioral;

